package com.ror.java.se.thread;

//需求：
//  完成生产者和消费者（等待唤醒机制）的代码
//  实现线程轮流交替执行的效果

import java.text.SimpleDateFormat;
import java.util.Date;

public class Demo10 {
    public static void main(String[] args) {
        Producer p = new Producer("厨师");
        Consumer c = new Consumer("食客");
        p.start();
        c.start();
    }

    private static class Producer extends Thread {
        public Producer(String name) {
            super(name);
        }

        @Override
        public void run() {
            while (true) {
                synchronized (Desk.lock) {
                    if (Desk.foodCount > 0) {
                        say("餐桌满了，我等待食客吃完这碗面条。");
                        try {
                            Desk.lock.wait();
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }
                    if (Desk.consumedCount >= Desk.consumedCountRequest) {
                        say("食客吃饱了，我不再做面条了。");
                        break;
                    }
                    Desk.foodCount++;
                    say("我做了一碗面条。");
                    Desk.lock.notifyAll();
                    say("我提醒食客该吃面条了。");
                }
            }
        }

        private void say(String words) {
            System.out.println("["
                    + new SimpleDateFormat("HH:mm:ss.S").format(new Date())
                    + "]" + Thread.currentThread().getName() + "：" + words);
        }
    }

    private static class Consumer extends Thread {
        public Consumer(String name) {
            super(name);
        }

        @Override
        public void run() {
            while (true) {
                synchronized (Desk.lock) {
                    if (Desk.foodCount <= 0) {
                        say("餐桌是空的，我等待厨师做一碗面条。");
                        try {
                            Desk.lock.wait();
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }
                    Desk.foodCount--;
                    Desk.consumedCount++;
                    say("我吃了一碗面条，这是第" + Desk.consumedCount + "碗。");
                    if (Desk.consumedCount >= Desk.consumedCountRequest) {
                        say("我吃饱了，不再继续吃面条了。");
                        Desk.lock.notifyAll();
                        say("我提醒厨师别再做面条了。");
                        break;
                    }
                    Desk.lock.notifyAll();
                    say("我提醒厨师该做面条了。");
                }
            }
        }

        private void say(String words) {
            System.out.println("["
                    + new SimpleDateFormat("HH:mm:ss.S").format(new Date())
                    + "]" + Thread.currentThread().getName() + "：" + words);
        }
    }

    private static class Desk {
        static int foodCount = 0; //当前资源个数
        static int consumedCount = 0; //当前处理资源个数
        static final int consumedCountRequest = 10; //需要处理资源个数
        static final Object lock = new Object();
    }
}
